package com.example.oss.aspect;


import com.alibaba.fastjson.JSON;
import com.example.oss.annotation.OperationLog;
import com.example.oss.entity.Student;
import com.example.oss.entity.WebLog;
import com.example.oss.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
@Aspect
public class WebAspect {

    @Pointcut("execution(* com.example.oss.controller.*.*(..))")
    public void webLog() {
    }

    /**
     * 记录http接口访问日志, 并在请求完成后清除ThreadLocal和SecurityContext中的信息
     * @param proceedingJoinPoint
     * @param operationLog
     * @return
     * @throws Throwable
     */
    @Around(value = "webLog() && @annotation(operationLog)")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint, OperationLog operationLog) throws Throwable {

        //获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            log.error("doAround error: 当前请求对象为null, attributes is null");
            return null;
        }
        //获取请求的返回值
        Object result = proceedingJoinPoint.proceed();

        HttpServletRequest request = attributes.getRequest();
        Student student = UserContextHolder.getUser();

        WebLog webLog = new WebLog();
        webLog.setDescription(operationLog.value());
        webLog.setIp(request.getRemoteAddr());
        webLog.setMethod(request.getMethod());
        webLog.setParam(JSON.toJSONString(request.getParameterMap()));
        webLog.setUrl(request.getRequestURL().toString());
        if (result != null) {
//            webLog.setResult(result.toString());
        }
        if (student != null) {
            webLog.setLoginUserId(student.getStuSn());
        }
        log.info(webLog.toString());

        //本次请求结束，删除用户信息，防止ThreadLocal内存泄漏
        UserContextHolder.clear();
        //清除SecurityContext的用户信息
        SecurityContextHolder.clearContext();

        return result;
    }


}